﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Windows.Threading;
using System.Threading;

using wmvSegments;

namespace asfbinScript
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private string m_scriptPath = null;

        private string m_curScript = null;
        private string m_outputPath = null;

        private string m_wmvRoot = null;
        private string m_aviOutput = null;

        private wmv2avi m_converter = null;
        private wmvCut  m_wmvCut = null;

        private string m_fileToChangeTime = "";

        private DispatcherTimer m_timer;

        private void ListFiles(string dirName, string searchPattern, ListBox listBox, bool recursive = false)
        {
            //add files to list box
            listBox.Items.Clear();

            DirectoryInfo di = new DirectoryInfo(dirName);
            if (!di.Exists)
            {
                return;
            }

            string[] directories = Directory.GetFiles(dirName, searchPattern, recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
            if(directories.Length > 0)
            {
                var sortedFiles = directories.OrderByDescending(d => new FileInfo(d).LastWriteTime); ;
                foreach (string name in sortedFiles)
                {
                    listBox.Items.Add(name);
                }
            }
        }

        public MainWindow()
        {
            InitializeComponent();            
            m_curScript = null;
            m_wmvRoot = null;
            m_scriptPath = null;            

            //  DispatcherTimer setup
            m_timer = new System.Windows.Threading.DispatcherTimer();
            m_timer.Tick += new EventHandler((s, e) =>
            {
                if (m_converter != null && m_converter.finish())
                {
                    m_converter = null;
                    MessageBox.Show("done.", "convert", MessageBoxButton.OK, MessageBoxImage.Information);
                }

                if (m_wmvCut != null && m_wmvCut.finish())
                {
                    m_wmvCut = null;
                    MessageBox.Show("done.", "wmv cut", MessageBoxButton.OK, MessageBoxImage.Information);
                }
            });
            m_timer.Interval = new TimeSpan(0, 0, 1);
            m_timer.Start();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
//             // create folder browser dialog            
//             var dlg = new Microsoft.Win32.OpenFileDialog();
// 
//             // Set filter for file extension and default file extension
//             dlg.DefaultExt = ".py";
//             dlg.Filter = "Avidemux project(.py)|*.py";
// 
//             // Display OpenFileDialog by calling ShowDialog method
//             Nullable<bool> result = dlg.ShowDialog();
//  
//             // Get the selected file name and display in a TextBox
//             if (result == true)
//             {
//                 ScriptPathText.Text = dlg.FileName;
//              }

            // create folder browser dialog
            var dlg = new System.Windows.Forms.FolderBrowserDialog();
            dlg.SelectedPath = Properties.Settings.Default.scriptPath;
            System.Windows.Forms.DialogResult result = dlg.ShowDialog();

            // Get the selected file name and display in a TextBox 
            if (result == System.Windows.Forms.DialogResult.OK)
            {
                // Open document 
                string dirName = dlg.SelectedPath;
                // save settings
                Properties.Settings.Default.scriptPath = dirName;
                Properties.Settings.Default.Save();
                m_scriptPath = dirName;

                ListFiles(m_scriptPath, "*.py", ScriptListBox);
            }
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            // create folder browser dialog
            var dlg = new System.Windows.Forms.FolderBrowserDialog();
            dlg.SelectedPath = Properties.Settings.Default.outputPath;
            System.Windows.Forms.DialogResult result = dlg.ShowDialog();

            // Get the selected file name and display in a TextBox 
            if (result == System.Windows.Forms.DialogResult.OK)
            {
                // Open document 
                string dirName = dlg.SelectedPath;
                Properties.Settings.Default.outputPath = dirName;
                Properties.Settings.Default.Save();
                m_outputPath = dirName;
            }
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            m_curScript = ScriptListBox.SelectedItem.ToString();

            //validate output path
            m_outputPath = null;
            DirectoryInfo fi = new DirectoryInfo(Properties.Settings.Default.outputPath);
            if (fi.Exists)
            {
                m_outputPath = Properties.Settings.Default.outputPath;
            }

            WmvCutLog.Text = "";

            // run the cut command
            if (m_curScript != null && m_outputPath != null && m_wmvCut == null)
            {
                m_wmvCut = new wmvCut(m_curScript, m_outputPath, wmvCutLog);
                m_wmvCut.cut();
            }
        }

        private void ScriptPathText_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Return)
            {
                DirectoryInfo fi = new DirectoryInfo(ScriptPathText.Text);
                if (fi.Exists)
                {
                    ListFiles(ScriptPathText.Text, "*.py", ScriptListBox);
                }
            }
        }

        private void Button_Click_3(object sender, RoutedEventArgs e)
        {
            // create folder browser dialog
            var dlg = new System.Windows.Forms.FolderBrowserDialog();
            dlg.SelectedPath = Properties.Settings.Default.wmvRoot;
            System.Windows.Forms.DialogResult result = dlg.ShowDialog();

            // Get the selected file name and display in a TextBox 
            if (result == System.Windows.Forms.DialogResult.OK)
            {
                // Open document 
                string dirName = dlg.SelectedPath;
                Properties.Settings.Default.wmvRoot = dirName;
                Properties.Settings.Default.Save();
                m_wmvRoot = dirName;

                ListFiles(m_wmvRoot, "*.wmv", Wmv2AviListBox);
            }

        }

        void wmvCutLog(object sender, DataReceivedEventArgs e)
        {
            string msg = e.Data;
            if (msg != null)
            {
                //To avoid cross thread exceptions.
                if (!WmvCutLog.CheckAccess())
                {
                    Dispatcher.Invoke((Action)delegate { this.WmvCutLog.AppendText(msg + "\r\n"); this.WmvCutLog.ScrollToEnd(); });
                }
                else
                {
                    WmvCutLog.AppendText(msg + "\r\n");
                    WmvCutLog.ScrollToEnd();
                }
            }
        }

        private void Button_Click_4(object sender, RoutedEventArgs e)
        {
            // create folder browser dialog
            var dlg = new System.Windows.Forms.FolderBrowserDialog();
            dlg.SelectedPath = Properties.Settings.Default.aviOutput;
            System.Windows.Forms.DialogResult result = dlg.ShowDialog();

            // Get the selected file name and display in a TextBox 
            if (result == System.Windows.Forms.DialogResult.OK)
            {
                // Open document 
                string dirName = dlg.SelectedPath;
                Properties.Settings.Default.aviOutput = dirName;
                Properties.Settings.Default.Save();
                m_aviOutput = dirName;
            }
        }        

        void UpdateProgress(object sender, DataReceivedEventArgs e)
        {
            string msg = e.Data;
            if (msg != null)
            {
                //get percentage from output
                string line = e.Data;
                if(line != null)
                {
                    // update progress bar
                    string patternPercentage = "\\((.*)%\\)";
                    Regex percentageRegex = new Regex(patternPercentage, RegexOptions.IgnoreCase);
                    Match m = percentageRegex.Match(line);
                    if (m.Success && m.Groups.Count > 0)
                    {
                        string percentage = m.Groups[m.Groups.Count-1].Captures[0].ToString().Replace(" ","");
                        if(percentage != null)
                        {                            
                            //To avoid cross thread exceptions.
                            if (!wmv2aviProgress.CheckAccess())
                            {
                                Dispatcher.Invoke((Action)
                                    delegate { this.wmv2aviProgress.Value = Convert.ToInt32(percentage); });
                            }
                            else
                            {
                                wmv2aviProgress.Value = Convert.ToInt32(percentage);
                            }
                        }
                    }     
           
                    // update log
                    //To avoid cross thread exceptions.
                    if (!Wmv2AviLog.CheckAccess())
                    {
                        Dispatcher.Invoke((Action)delegate { this.Wmv2AviLog.AppendText(msg + "\r\n"); this.Wmv2AviLog.ScrollToEnd(); });
                    }
                    else
                    {
                        Wmv2AviLog.AppendText(msg + "\r\n");
                        Wmv2AviLog.ScrollToEnd();
                    }
                }
            }
        }

        private void Button_Click_5(object sender, RoutedEventArgs e)
        {
            wmv2aviProgress.Value = 0;
            Wmv2AviLog.Text = "";

            string wmvName = Wmv2AviListBox.SelectedItem.ToString();
            if (wmvName != null && m_converter==null)
            {
                m_converter = new wmv2avi(m_wmvRoot, m_aviOutput, UpdateProgress);
                m_converter.Convert(wmvName);
            }
        }

        private void WmvRootText_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Return)
            {
                DirectoryInfo fi = new DirectoryInfo(ScriptPathText.Text);
                if (fi.Exists)
                {
                    ListFiles(WmvRootText.Text, "*.wmv", Wmv2AviListBox);
                }
            }
        }

        private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (Wmv2AviTab.IsSelected && m_wmvRoot==null)
            {
                m_wmvRoot = Properties.Settings.Default.wmvRoot;
                m_aviOutput = Properties.Settings.Default.aviOutput;
                ListFiles(m_wmvRoot, "*.wmv", Wmv2AviListBox, true);  
            }
            if (WmvCutTab.IsSelected && m_scriptPath == null)
            {
                m_scriptPath = Properties.Settings.Default.scriptPath;
                m_outputPath = Properties.Settings.Default.outputPath;
                ListFiles(m_scriptPath, "*.py", ScriptListBox);  
            }
            
        }

        private void Button_Click_6(object sender, RoutedEventArgs e)
        {
            if (m_converter != null)
            {
                m_converter.stop();
                m_converter = null;                
            }
        }

        private void UpdateFileTime()
        {
            FileInfo fi = new FileInfo(m_fileToChangeTime);
            if (fi.Exists)
            {
                CreatedTime_Src.Text = fi.CreationTime.ToString();
                ModifiedTime_Src.Text = fi.LastWriteTime.ToString();
                AccessedTime_Src.Text = fi.LastAccessTime.ToString();                    
            }
            else
            {
                m_fileToChangeTime = "";
            }
        }

        private void TextBox_ChangeTime_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Return)
            {
                m_fileToChangeTime = (sender as TextBox).Text;
                UpdateFileTime();
            }
        }

        private void Button_Click_ChangeFileTime(object sender, RoutedEventArgs e)
        {
            if (m_fileToChangeTime != "")
            {
                DateTime time = TimeToChange.SelectedDate.Value.Date;
                if(CheckBox_Created.IsChecked == true)
                {
                    File.SetCreationTime(m_fileToChangeTime, time);
                }
                if (CheckBox_Modified.IsChecked == true)
                {
                    File.SetLastWriteTime(m_fileToChangeTime, time);
                }
                if (CheckBox_Accessed.IsChecked == true)
                {
                    File.SetLastAccessTime(m_fileToChangeTime, time);
                }
                UpdateFileTime();
            }
        }

        public void FileToChangeTime_OnDragOver(object sender, DragEventArgs e)
        {

            e.Effects = DragDropEffects.All;
            e.Handled = true;
        }

        private void FileToChangeTime_Drop(object sender, DragEventArgs e)
        {
            object text = e.Data.GetData(DataFormats.FileDrop);
            TextBox tb = sender as TextBox;
            if (tb != null)
            {
                tb.Text = string.Format("{0}", ((string[])text)[0]);
                m_fileToChangeTime = tb.Text;
                UpdateFileTime();
            }
        }

        private void TimeToChange_Drop(object sender, DragEventArgs e)
        {
            object text = e.Data.GetData(DataFormats.FileDrop);
            DatePicker dp = sender as DatePicker;
            if (dp != null)
            {
                string path = string.Format("{0}", ((string[])text)[0]);
                FileInfo fi = new FileInfo(path);
                dp.Text = fi.LastWriteTime.ToString();
            }
        }

    }
}
